package com.xhs.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.concurrent.*;

/**
 * @desc: CompletableFuture  任务获取方式
 * get()
 * get(long timeout, TimeUnit unit)
 * getNow(T valueIfAbsent)
 * join()
 * @projectName: java-tools-parent
 * @author: xhs
 * @date: 2025-08-09 周六 16:10
 */
@Slf4j
@RestController
@RequestMapping("/completableFuture4")
public class CompletableFuture4Controller {

    @Resource
    private Executor taskExecutor;

    /**
     * 任务一和任务二执行完成后,再执行任务三，接收任务一二的结果作为参数,有返回值
     */
    @GetMapping("/test01")
    public void test() throws ExecutionException, InterruptedException, TimeoutException {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            log.info("线程：" + Thread.currentThread().getName() + " 返回数据");
            // 睡眠10秒
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 模拟抛出异常
//            int i = 10/0;
            return "hello world";
        }, taskExecutor);


        // 阻塞等待，直到future线程执行完成，唤醒主线程
        log.info("线程：{} 获取结果: {}", Thread.currentThread().getName(), future.get());

        // 超时等待获取，直到超时时间，抛出超时异常
        log.info("future.get():{}", future.get(1, TimeUnit.SECONDS));

        // 获取不到，给指定默认值
        log.info("future.getNow('defaultValue'):{}", future.getNow("defaultValue"));

        /**
         * join与get的区别
         * join 抛出未经检查的CompletionException 是运行时异常，不需要抛出去或者捕获,
         *     阻塞线程不支持中断
         *     使用场景：lambda表达式中，不需要中断
         * get 抛出已检查的 ExecutionException 和 InterruptedException 需要捕获或者抛出去
         *     阻塞线程支持中断  需要明确处理中断或执行异常时使用
         */
        log.info("future.join():{}", future.join());

    }
}
